using System;

namespace RapidHDL
{
	/// <summary>
	/// Summary description for Component.
	/// </summary>
	public class Component
	{
		Component oParentComponent;
		int iHirarchyLevel;

		string sComponentTypeId;

		RapidHardware oRapidHardware;
		string sName;
		double dCombinationalDelay;

		System.Collections.Hashtable oNodeVectors;
		System.Collections.Hashtable oComponents;

		System.Collections.Hashtable oSinkNodeVectors;
		System.Collections.Hashtable oSourceNodeVectors;
		System.Collections.Hashtable oPassThroughNodeVectors;

		internal System.Collections.ArrayList InputNodeVectors;
		internal System.Collections.ArrayList OutputNodeVectors;
		internal System.Collections.ArrayList ConnectionOnlyNodeVectors;
		internal System.Collections.ArrayList RedundantNodeVectors;

		SimulationState eSimulationStateOutput;
		ComponentVerilog oComponentVerilog;

		EventNode oEventNodeStabilize;

		protected bool IsComponentWellFormed;
		protected bool IsComponentCheckingForWellFormed;

		bool bRegisteredComponent;

		public Component(Component poParentComponent, string psName)
		{
			Initialize();
			oParentComponent = poParentComponent;
			oRapidHardware = oParentComponent.RapidHardware;
			sName = psName;
			oParentComponent.Components.Add(psName,this);
			iHirarchyLevel = oParentComponent.HirarchyLevel + 1;
		}

		public Component(RapidHardware poRapidHardware, string psName)
		{
			Initialize();
			oRapidHardware = poRapidHardware;	
			sName = psName;
			oParentComponent = null;
			iHirarchyLevel = 1;
		}

		private void Initialize()
		{
			dCombinationalDelay = 0;
			oNodeVectors = new System.Collections.Hashtable();
			oComponents = new System.Collections.Hashtable();

			oSinkNodeVectors = new System.Collections.Hashtable();
			oSourceNodeVectors = new System.Collections.Hashtable();
			oPassThroughNodeVectors = new System.Collections.Hashtable();

			oComponentVerilog = new ComponentVerilog(this);

			eSimulationStateOutput = SimulationState.Stable;
			bRegisteredComponent = false;

			IsComponentWellFormed = false;
			IsComponentCheckingForWellFormed = false;
			sComponentTypeId = this.GetType().ToString();
			sComponentTypeId = sComponentTypeId.Replace(".","");
		}

		public NodeVector CreateNodeVector(string psName, int piSize)
		{
			return new NodeVector(this,psName, piSize);
		}

		public NodeVector CreateNodeVector(string psName, int piSize, NodeFlowType peNodeFlowType)
		{
			return new NodeVector(this,psName, piSize,peNodeFlowType);
		}

		public virtual string GenerateVerilog()
		{
			return "";
		}

		public double CombinationalDelay
		{
			get{return dCombinationalDelay;}
			set{dCombinationalDelay = value;}
		}

		public SimulationState SimulationStateInput
		{
			get
			{
				foreach(NodeVector oNodeVector in oSinkNodeVectors.Values)
				{
					foreach(Node oNode in oNodeVector.Nodes)
					{
						if (oNode.Net.SimulationStateOutput == SimulationState.Unstable)
						{
							SimulationTraceLog("This component's input node is unstable",oNode);
							return SimulationState.Unstable;
						}
					}
				}
				SimulationTraceLog("This component's inputs are stable",null);
				return SimulationState.Stable;
			}
		}

		public SimulationState SimulationStateOutput
		{
			get{return eSimulationStateOutput;}
		}

		public RapidHardware RapidHardware
		{
			get{return oRapidHardware;}
		}

		public System.Collections.Hashtable NodeVectors
		{
			get {return oNodeVectors;}
		}

		public System.Collections.Hashtable SinkNodeVectors
		{
			get {return oSinkNodeVectors;}
		}

		public System.Collections.Hashtable SourceNodeVectors
		{
			get {return oSourceNodeVectors;}
		}

		public System.Collections.Hashtable PassthroughNodeVectors
		{
			get {return oPassThroughNodeVectors;}
		}

		public ComponentVerilog ComponentVerilog
		{
			get {return oComponentVerilog;}
		}

		public int HirarchyLevel
		{
			get {return iHirarchyLevel;}
		}

		public virtual bool RegisteredComponent
		{
			get {return bRegisteredComponent;}
		}

		public System.Collections.Hashtable Components
		{
			get {return oComponents;}
		}

		public string Name
		{
			get{return sName;}
		}

		public string HirarchicalName
		{
			get
			{
				if (oParentComponent == null)
					return Name;
				else
					return oParentComponent.HirarchicalName + "." + Name;
			}
		}

		public virtual void GenerateStructure()
		{
		}

		public void BaseGenerateStructure()
		{
			GenerateStructure();

			foreach(Component oComponent in oComponents.Values)
			{
				oComponent.BaseGenerateStructure();
			}
		}

		public void SimulationDestabilizeComponent()
		{
			// if component output is already unstable...
			//		we only need to cancel any scheduled stabilization event
			if (eSimulationStateOutput == SimulationState.Unstable)
			{
				SimulationTraceLog("SimulationDestabilizeComponent already unstable",null);

				// cancel stabilization event
				if (oEventNodeStabilize != null)
					oRapidHardware.Simulation.Clock.UnlinkNode(oEventNodeStabilize);
				oEventNodeStabilize = null;
				return;
			}

			SimulationTraceLog("SimulationDestabilizeComponent NOT already unstable",null);

			// otherwise, we were a stable component 
			// we need to alert nets driven by compoenet
			// that the net inputs are now unstable
			eSimulationStateOutput = SimulationState.Unstable;
			foreach(NodeVector oNodeVector in oSourceNodeVectors.Values)
			{
				int i = 1;
				foreach(Node oNode in oNodeVector.Nodes)
				{
					SimulationTraceLog("Destabilize Node Net, loop "  + i.ToString() + " of " + oNodeVectors.Count.ToString() ,oNode);
					oNode.Net.SimulationDestabilizeNet();
				}
			}
		}

		public void SimulationStabilizeComponent()
		{
			SimulationTraceLog("SimulationStabilizeComponent",null);

			// should never call this when node is already stable
			System.Diagnostics.Debug.Assert(eSimulationStateOutput != SimulationState.Stable);

			// check to see if the inputs are all stable
			if (this.SimulationStateInput != SimulationState.Stable)
			{
				return;  // unstable inputs mean unstable net
			}

			// if there is no propagation delay, immediately stabilize output too
			//     but, if there is a propagation delay, schedule stabilization event on clock
			if (dCombinationalDelay == 0)
			{
				SimulationTraceLog("Stabilization With No Combinational Delay",null);
				SimulationStabilizeComponentOutputEvent(0);
			}
			else
			{
				SimulationTraceLog("Schedule Stabilization AFTER Combinational Delay",null);

				if (oEventNodeStabilize != null)
					oRapidHardware.Simulation.Clock.UnlinkNode(oEventNodeStabilize);
				oEventNodeStabilize = oRapidHardware.Simulation.Clock.ScheduleClockEvent(dCombinationalDelay,new Clock.ClockEvent(this.SimulationStabilizeComponentOutputEvent)); 
			}
		}

		public virtual void CalculateOutput()
		{
		}

		private void BaseCalculateOutput()
		{
			foreach(NodeVector oNodeVector in oSourceNodeVectors.Values)
			{
				SimulationTraceLog("Start CalcluateOutput {" + oNodeVector.Name + " = '" + oNodeVector.NodeVectorAsString + "'}",null);
			}
			CalculateOutput();
			foreach(NodeVector oNodeVector in oSourceNodeVectors.Values)
			{
				SimulationTraceLog("Finished CalcluateOutput {" + oNodeVector.Name + " = '" + oNodeVector.NodeVectorAsString + "'}",null);
			}
		}

		public void SimulationStabilizeComponentOutputEvent(long plTimeNow)
		{
			SimulationTraceLog("SimulationSabilizeComponentOutputEvent at time " + plTimeNow.ToString() + "/" + oRapidHardware.Simulation.Clock.TimeNow.ToString() ,null);

			// if this happens, there is a fundamental scheduling problem
			System.Diagnostics.Debug.Assert((oEventNodeStabilize == null & plTimeNow == 0 | plTimeNow != 0),"Phantom EventNodeStabilize event scheduled in component!");

			// should never call this event if node is already stable
			System.Diagnostics.Debug.Assert(eSimulationStateOutput != SimulationState.Stable,"Net stabilization event called when compoent is already stable!");

			BaseCalculateOutput();
			SimulationTraceLog("Output state marked stable",null);
			eSimulationStateOutput = SimulationState.Stable;
			foreach(NodeVector oNodeVector in oSourceNodeVectors.Values)
			{
				int i = 1;
				foreach(Node oNode in oNodeVector.Nodes)
				{
					SimulationTraceLog("Stabilize Node's Net, loop "  + i.ToString() + " of " + oNodeVectors.Count.ToString() ,oNode);
					oNode.Net.SimulationStabilizeNet();
					i++;
				}
			}
		}

		protected virtual Component TestBuildStructure(Component poTopComponent, string psTestName)
		{
			return null;
		}

		protected virtual string TestComponent(Clock poClock, Component poTestComponent, string psTestName)
		{
			return "";
		}

		public string BaseTestComponent(RapidHardware poRapidHardware, string psTestName)
		{
			string sResult;
			poRapidHardware.Simulation.Clock.Reset();
			Component oComponent = TestBuildStructure(poRapidHardware.Structure.TopLevelComponent,psTestName);
			if (oComponent == null)
				return "";
			oComponent.BaseGenerateStructure();
			if (!oComponent.SortStructure())
				return "";
			if (!oComponent.ValidateWellFormedComponent())
				return "";
			sResult = TestComponent(poRapidHardware.Simulation.Clock,oComponent,psTestName);
			poRapidHardware.Structure.TopLevelComponent.Components.Remove(oComponent.Name);
			return sResult;
		}

		private void SimulationTraceLog(string psLogEntry, Node poNode)
		{
			string sLogEntry = "Component: {" + this.HirarchicalName + "}";
			if (poNode != null)
				sLogEntry += " {Node: " + poNode.Name + " = '" + poNode.NodeState.ToString() + "'}";
			sLogEntry += " " + psLogEntry;
			oRapidHardware.InternalLog.Log(LogType.SimulationTrace,sLogEntry);
		}


		public virtual bool TransformStructureToVerilog()
		{
			ComponentVerilog.VerilogTraceLog("No override of TransforStructureToVerilog in derrived component");

			ComponentVerilog.WriteVerilogText("// Component Did Not Write Any Custom Verilog");
			return true;
		}

		internal Component ParentComponent
		{
			get{return oParentComponent;}
		}

		public bool BaseTransformStructureToVerilog()
		{
			foreach(Component oComponent in oComponents.Values)
			{
				if (!oComponent.BaseTransformStructureToVerilog())
					return false;
			}
			oComponentVerilog.VerilogTraceLog("Starting VerilogTransform");
			return oComponentVerilog.TransformStructureToVerilog();
		}

		public bool IsTestComponentSameOrChild(Component poTestComponent)
		{
			int iTestHirarchyLevel;
			Component oTestParentComponent;

			iTestHirarchyLevel = poTestComponent.HirarchyLevel;
			oTestParentComponent = poTestComponent;
			while(iTestHirarchyLevel > iHirarchyLevel)
			{
				iTestHirarchyLevel--;
				oTestParentComponent = oTestParentComponent.ParentComponent;
			}
			return (oTestParentComponent == this);
		}

		public ComponentRelationship GetComponentRelationship(Component poComponent)
		{
			ComponentRelationship eComponentRelationship;

			if(poComponent == this)
				return ComponentRelationship.ThisComponent;

			if (poComponent.HirarchyLevel == this.HirarchyLevel)
			{
				return ComponentRelationship.CousinComponent;
			}

			if (poComponent.HirarchyLevel > this.HirarchyLevel)
			{
				eComponentRelationship = poComponent.GetComponentRelationship(this.ParentComponent);
				if (eComponentRelationship == ComponentRelationship.ThisComponent)
					return ComponentRelationship.ChildComponent;
				else
					return ComponentRelationship.CousinComponent;
			}
			else
			{
				eComponentRelationship = this.GetComponentRelationship(poComponent.ParentComponent);
				if (eComponentRelationship == ComponentRelationship.ThisComponent)
					return ComponentRelationship.ParentComponent;
				else
					return ComponentRelationship.CousinComponent;
			}
		}


		internal bool SortStructure()
		{
			bool bIsNodeFloating;

			// necessary
			// sort node vectors based on flow type
			foreach(NodeVector oNodeVector in oNodeVectors.Values)
			{
				if(oNodeVector.NodeFlowType == NodeFlowType.Source)
				{
					oSourceNodeVectors.Add(oNodeVector.Name,oNodeVector);
				}
				else 
				{
					if(oNodeVector.NodeFlowType == NodeFlowType.Sink)
					{
						oSinkNodeVectors.Add(oNodeVector.Name,oNodeVector);

						// check for floating sink nodes
						// floating node is one without a source
						// and that doesn't flow to level 2 of hirarchy
						foreach(Node oNode in oNodeVector.Nodes)
						{
							if (oNode.Net.SourceNodes.Count == 0)
							{
								if(oNode.ParentNodeVector.ParentComponent.HirarchyLevel > 2)
								{
									bIsNodeFloating = true;
									foreach(Node oPassNode in oNode.Net.PassthroughNodes)
									{
										if(oPassNode.ParentNodeVector.ParentComponent.HirarchyLevel <= 2)
										{
											bIsNodeFloating = false;
											continue;
										}
									}

									if (bIsNodeFloating)
									{
										System.Diagnostics.Debug.Fail("Sink Node " + oNode.HirarchicalName + " is floating, with no source.");
										return false;
									}
								}
							}
						}
					}
					else
					{
						oPassThroughNodeVectors.Add(oNodeVector.Name,oNodeVector);

						// check for floating passthrough nodes
						// should have a sink or soruce, at least
						foreach(Node oNode in oNodeVector.Nodes)
						{
							if (oNode.Net.SinkNodes.Count == 0 && oNode.Net.SourceNodes.Count == 0)
							{
								System.Diagnostics.Debug.Fail("Sink Node " + oNode.HirarchicalName + " is floating, with no source or sink.");
								return false;
							}
						}
					}
				}
			}

			foreach(Component oComponent in oComponents.Values)
			{
				if (oComponent.SortStructure() == false)
					return false;
			}			

			return true;
		}

		public bool ValidateWellFormedComponent()
		{

			foreach(Component oComponent in oComponents.Values)
			{
				oComponent.ValidateWellFormedComponent();
			}

			return RecurseCheckWellFormedComponent();

			// loop to the bottom of the component hirarchy
			// and trace paths in each component
		}


		protected bool RecurseCheckWellFormedComponent()
		{
			if (IsComponentCheckingForWellFormed)
			{
				System.Diagnostics.Debug.Fail(this.HirarchicalName + " is not in a wellformed configuration.");
				return false;
			}

			if (IsComponentWellFormed)
				return true;

			IsComponentCheckingForWellFormed = true;
			
			foreach(NodeVector oNodeVector in oSourceNodeVectors.Values)
			{
				foreach(Node oNode in oNodeVector.Nodes)
				{
					foreach(Node oSinkNode in oNode.Net.SinkNodes)
					{
						Component oComponent = oSinkNode.ParentNodeVector.ParentComponent;
						if (oComponent.RegisteredComponent == false)
						{
							if (oComponent.RecurseCheckWellFormedComponent() == false)
								return false;
						}
					}
				}
			}

			IsComponentCheckingForWellFormed = false;
			return true;
		}

		public string ComponentTypeId
		{
			get
			{
				return sComponentTypeId;
			}
			set{sComponentTypeId = value;}
		}

		public void PrepareVerilogStructure()
		{	
			foreach(Component oComponent in oComponents.Values)
			{
				oComponent.PrepareVerilogStructure();
				SpliceConnectingVectors(oComponent);
			}

			ComponentVerilog.VerilogTraceLog("************* Start Preperation of Verilog Structure ***************");

			InputNodeVectors = new System.Collections.ArrayList();
			OutputNodeVectors = new System.Collections.ArrayList();
			ConnectionOnlyNodeVectors = new System.Collections.ArrayList();
			RedundantNodeVectors = new System.Collections.ArrayList();

			foreach(NodeVector oNodeVector in oSourceNodeVectors.Values)
			{
				StructureNodeVector(oNodeVector);
			}

			foreach(NodeVector oNodeVector in oSinkNodeVectors.Values)
			{
				StructureNodeVector(oNodeVector);
			}

			foreach(NodeVector oNodeVector in oPassThroughNodeVectors.Values)
			{
				StructureNodeVector(oNodeVector);
			}

			ComponentVerilog.VerilogTraceLog("************* End Preperation of Verilog Structure ***************");
		}
	
		private void SpliceConnectingVectors(Component poComponent)
		{
			string sNodeVectorName;
			NodeVector oNewNodeVector;
			System.Collections.ArrayList oComponentLevelNetNodes;

			ComponentVerilog.VerilogTraceLog("----- Start Splice In of Any Needed Routing Nodes --------");

			foreach(NodeVector oNodeVector in poComponent.InputNodeVectors)
			{
				// scan the nodes in the vector
				// and make sure that it is connected to a node in the parent
				// if not connected, then duplicate the entire vector in the parent and continue
				foreach(Node oNode in oNodeVector.Nodes)
				{
					oComponentLevelNetNodes = oNode.Net.SelectNodes(this);
					if (oComponentLevelNetNodes.Count == 0) 
					{
						ComponentVerilog.VerilogTraceLog("Child input node has no counterpart in parent",oNode);

						sNodeVectorName = GetUniqueNodeVectorName(poComponent.Name + "_" + oNodeVector.Name);
						oNewNodeVector = CreateNodeVector(sNodeVectorName,oNodeVector.Size);
						oNewNodeVector.Nodes = oNodeVector.Nodes;
						oPassThroughNodeVectors.Add(oNewNodeVector.Name,oNewNodeVector);

						ComponentVerilog.VerilogTraceLog("created new vector to link with node",oNewNodeVector,oNode);
						break;
					}
				}
			}

			foreach(NodeVector oNodeVector in poComponent.OutputNodeVectors)
			{
				foreach(Node oNode in oNodeVector.Nodes)
				{
					oComponentLevelNetNodes = oNode.Net.SelectNodes(this);
					if (oComponentLevelNetNodes.Count == 0) 
					{
						ComponentVerilog.VerilogTraceLog("Child output node has no counterpart in parent",oNode);

						sNodeVectorName = GetUniqueNodeVectorName(poComponent.Name + "_" + oNodeVector.Name);
						oNewNodeVector = CreateNodeVector(sNodeVectorName,oNodeVector.Size);
						oPassThroughNodeVectors.Add(oNewNodeVector.Name,oNewNodeVector);
						oNewNodeVector.Nodes = oNodeVector.Nodes;

						ComponentVerilog.VerilogTraceLog("Created new vector to link with node.",oNewNodeVector,oNode);
						break;
					}
				}
			}

			ComponentVerilog.VerilogTraceLog("----- End Splice In of Any Needed Routing Nodes --------");

		}

		private void StructureNodeVector(NodeVector poNodeVector)
		{
			NodeStructure eNodeStructure;

			eNodeStructure = poNodeVector.OrganizeNodeStructure();
			switch(eNodeStructure)
			{
				case NodeStructure.Connection:
					ComponentVerilog.VerilogTraceLog("NodeVector classified as Connection",poNodeVector);
					ConnectionOnlyNodeVectors.Add(poNodeVector);
					break;
				case NodeStructure.Input:
					ComponentVerilog.VerilogTraceLog("NodeVector classified as Input",poNodeVector);
					InputNodeVectors.Add(poNodeVector);
					break;
				case NodeStructure.Output:
					ComponentVerilog.VerilogTraceLog("NodeVector classified as Output",poNodeVector);
					OutputNodeVectors.Add(poNodeVector);
					break;
				case NodeStructure.Redundant:
					ComponentVerilog.VerilogTraceLog("NodeVector classified as Redundant",poNodeVector);
					RedundantNodeVectors.Add(poNodeVector);
					break;
				case NodeStructure.Mixed:
					ComponentVerilog.VerilogTraceLog("NodeVector classified as Mixed... Splitting",poNodeVector);
					SplitMixedNodeVector(poNodeVector);
					break;
			}
		}

		private void SplitMixedNodeVector(NodeVector poNodeVector)
		{
			Node oTempNode;
			int iConnectionNodes = 0;
			int iOutputNodes = 0;
			int iInputNodes = 0;

			string sNodeVectorName;

			NodeVector oConnectionNodeVector = null;
			NodeVector oInputNodeVector = null;
			NodeVector oOutputNodeVector = null;
			
			foreach(Node oNode in poNodeVector.Nodes)
			{
				switch(oNode.NodeStructure)
				{
					case NodeStructure.Connection:
						iConnectionNodes++;
						break;
					case NodeStructure.Input:
						iInputNodes++;
						break;
					case NodeStructure.Output:
						iOutputNodes++;
						break;
				}
			}

			if (iConnectionNodes > 0)
			{
				sNodeVectorName = GetUniqueNodeVectorName(poNodeVector.Name + "_c");
				oConnectionNodeVector = this.CreateNodeVector(sNodeVectorName,iConnectionNodes);
				ConnectionOnlyNodeVectors.Add(oConnectionNodeVector);
				oConnectionNodeVector.NodeStructure = NodeStructure.Connection;
				ComponentVerilog.VerilogTraceLog("Created A Split Connection NodeVector",oConnectionNodeVector);
			}

			if (iInputNodes > 0)
			{
				sNodeVectorName = GetUniqueNodeVectorName(poNodeVector.Name + "_i");
				oInputNodeVector = this.CreateNodeVector(sNodeVectorName,iInputNodes);
				InputNodeVectors.Add(oInputNodeVector);
				oInputNodeVector.NodeStructure = NodeStructure.Input;
				ComponentVerilog.VerilogTraceLog("Created A Split Input NodeVector",oInputNodeVector);
			}

			if (iOutputNodes > 0)
			{
				sNodeVectorName = GetUniqueNodeVectorName(poNodeVector.Name + "_o");
				oOutputNodeVector = this.CreateNodeVector(sNodeVectorName,iOutputNodes);
				oConnectionNodeVector.NodeStructure = NodeStructure.Output;
				OutputNodeVectors.Add(oOutputNodeVector);
				ComponentVerilog.VerilogTraceLog("Created A Split Output NodeVector",oOutputNodeVector);
			}

			iConnectionNodes = 0;
			iInputNodes = 0;
			iOutputNodes = 0;

			ComponentVerilog.VerilogTraceLog("Making NodeVector Redundant",poNodeVector);
			foreach(Node oNode in poNodeVector.Nodes)
			{
				switch(oNode.NodeStructure)
				{
					case NodeStructure.Connection:
						ComponentVerilog.VerilogTraceLog("Connecting this node to new Split Connection NodeVector",oNode);

						oTempNode = (Node)oConnectionNodeVector.Nodes[iConnectionNodes];
						oTempNode.NodeStructure = NodeStructure.Connection;
						oNode.Net.Connect(oTempNode.Net);
						iConnectionNodes++;
						break;
					case NodeStructure.Input:
						ComponentVerilog.VerilogTraceLog("Connecting this node to new Split Input NodeVector",oNode);

						oTempNode = (Node)oInputNodeVector.Nodes[iInputNodes];
						oTempNode.NodeStructure = NodeStructure.Input;
						oNode.Net.Connect(oTempNode.Net);
						iInputNodes++;
						break;
					case NodeStructure.Output:
						ComponentVerilog.VerilogTraceLog("Connecting this node to new Split Output NodeVector",oNode);

						oTempNode = (Node)oConnectionNodeVector.Nodes[iOutputNodes];
						oTempNode.NodeStructure = NodeStructure.Output;
						oNode.Net.Connect(oTempNode.Net);
						iOutputNodes++;
						break;
				}
				oNode.NodeStructure = NodeStructure.Redundant;
			}

			/*if (iConnectionNodes > 0)
			{
				StructureNodeVector(oConnectionNodeVector);
			}

			if (iInputNodes > 0)
			{
				StructureNodeVector(oInputNodeVector);
			}

			if (iOutputNodes > 0)
			{
				StructureNodeVector(oOutputNodeVector);
			}*/

			poNodeVector.NodeStructure = NodeStructure.Redundant;
			RedundantNodeVectors.Add(poNodeVector);
		}

		private string GetUniqueNodeVectorName(string psName)
		{
			string sName = psName;
			int iSuffix = 0;

			while(oNodeVectors.ContainsKey(sName))
			{
				sName = psName + iSuffix.ToString();
			}

			return sName;
		}
		
		/*public void ParseNetStructure()
		{
			foreach(Component oComponent in oComponents.Values)
				oComponent.ParseNetStructure();

			ComponentVerilog.VerilogTraceLog("*****************  Start Parsing Net Structure For Verilog ****************");

			foreach(NodeVector oNodeVector in oSinkNodeVectors.Values)
				oNodeVector.ParseNetStructure();

			foreach(NodeVector oNodeVector in oSourceNodeVectors.Values)
				oNodeVector.ParseNetStructure();

			foreach(NodeVector oNodeVector in oPassThroughNodeVectors.Values)
				oNodeVector.ParseNetStructure();

			ComponentVerilog.VerilogTraceLog("***************** Finished Parsing Net Structure For Verilog ****************");
		}*/

	}
}
